home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / utilit~1 / initsnb.zoo / init / sh / error.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-09  |  6.3 KB  |  236 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Kenneth Almquist.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. static char sccsid[] = "@(#)error.c    5.1 (Berkeley) 3/7/91";
  39. #endif /* not lint */
  40.  
  41. /*
  42.  * Errors and exceptions.
  43.  */
  44.  
  45. #include "shell.h"
  46. #include "main.h"
  47. #include "options.h"
  48. #include "output.h"
  49. #include "error.h"
  50. #include <signal.h>
  51. #ifdef __STDC__
  52. #include "stdarg.h"
  53. #else
  54. #include <varargs.h>    
  55. #endif
  56. #include <errno.h>
  57.  
  58.  
  59. /*
  60.  * Code to handle exceptions in C.
  61.  */
  62.  
  63. struct jmploc *handler;
  64. int exception;
  65. volatile int suppressint;
  66. volatile int intpending;
  67. char *commandname;
  68.  
  69.  
  70. /*
  71.  * Called to raise an exception.  Since C doesn't include exceptions, we
  72.  * just do a longjmp to the exception handler.  The type of exception is
  73.  * stored in the global variable "exception".
  74.  */
  75.  
  76. void
  77. exraise(e) {
  78.     if (handler == NULL)
  79.         abort();
  80.     exception = e;
  81.     longjmp(handler->loc, 1);
  82. }
  83.  
  84.  
  85. /*
  86.  * Called from trap.c when a SIGINT is received.  (If the user specifies
  87.  * that SIGINT is to be trapped or ignored using the trap builtin, then
  88.  * this routine is not called.)  Suppressint is nonzero when interrupts
  89.  * are held using the INTOFF macro.  The call to _exit is necessary because
  90.  * there is a short period after a fork before the signal handlers are
  91.  * set to the appropriate value for the child.  (The test for iflag is
  92.  * just defensive programming.)
  93.  */
  94.  
  95. void
  96. onint() {
  97.     if (suppressint) {
  98.         intpending++;
  99.         return;
  100.     }
  101.     intpending = 0;
  102. #ifdef BSD
  103.     sigsetmask(0);
  104. #endif
  105.     if (rootshell && iflag)
  106.         exraise(EXINT);
  107.     else
  108.         _exit(128 + SIGINT);
  109. }
  110.  
  111.  
  112.  
  113. void
  114. error2(a, b)
  115.     char *a, *b;
  116.     {
  117.     error("%s: %s", a, b);
  118. }
  119.  
  120.  
  121. /*
  122.  * Error is called to raise the error exception.  If the first argument
  123.  * is not NULL then error prints an error message using printf style
  124.  * formatting.  It then raises the error exception.
  125.  */
  126.  
  127. #ifdef __STDC__
  128. void
  129. error(char *msg, ...) {
  130. #else
  131. void
  132. error(va_alist)
  133.     va_dcl
  134.     {
  135.     char *msg;
  136. #endif
  137.     va_list ap;
  138.  
  139.     CLEAR_PENDING_INT;
  140.     INTOFF;
  141. #ifdef __STDC__
  142.     va_start(ap, msg);
  143. #else
  144.     va_start(ap);
  145.     msg = va_arg(ap, char *);
  146. #endif
  147. #ifdef DEBUG
  148.     if (msg)
  149.         TRACE(("error(\"%s\") pid=%d\n", msg, getpid()));
  150.     else
  151.         TRACE(("error(NULL) pid=%d\n", getpid()));
  152. #endif
  153.     if (msg) {
  154.         if (commandname)
  155.             outfmt(&errout, "%s: ", commandname);
  156.         doformat(&errout, msg, ap);
  157.         out2c('\n');
  158.     }
  159.     va_end(ap);
  160.     flushall();
  161.     exraise(EXERROR);
  162. }
  163.  
  164.  
  165.  
  166. /*
  167.  * Table of error messages.
  168.  */
  169.  
  170. struct errname {
  171.     short errcode;        /* error number */
  172.     short action;        /* operation which encountered the error */
  173.     char *msg;        /* text describing the error */
  174. };
  175.  
  176.  
  177. #define ALL (E_OPEN|E_CREAT|E_EXEC)
  178.  
  179. STATIC const struct errname errormsg[] = {
  180.     EERROR, ALL,    "generic error",
  181.     EDRVNR, ALL,    "drive not ready",
  182.     EUNCMD, ALL,    "unknown drive command",
  183.     E_CRC, ALL,    "CRC error",
  184.     EBADRQ, ALL,    "bad drive request",
  185.     E_SEEK, ALL,    "seek error",
  186.     EMEDIA, ALL,    "unknown medium format",
  187.     ESECNF, ALL,    "sector not found",
  188.     EPAPER, ALL,    "out of paper",
  189.     EWRITEF, ALL,    "write fault",
  190.     EREADF, ALL,    "read fault",
  191.     EROFS, E_CREAT,    "read-only filesystem",
  192.     E_CHNG, ALL,    "media changed",
  193.     EUNDEV, ALL,    "unknown drive",
  194.     EBADSF, ALL,    "bad sector on format",
  195.     EOTHER, ALL,    "insert other disk request",
  196.     EINVAL, ALL,    "unimplemented system call",
  197.     ENOENT, ALL,    "no such file or directory (or pid)",
  198.     EPATH, ALL,    "path not found",
  199.     EMFILE, E_OPEN|E_CREAT,    "no more open files",
  200.     EACCESS, ALL,    "access denied",
  201.     EBADF, ALL,    "bad file descriptor",
  202.     ENOMEM, ALL,    "out of memory",
  203.     EFAULT, ALL,    "invalid memory block address",
  204.     ENXIO, ALL,    "invalid drive specification",
  205.     EXDEV, ALL,    "cannot move across file systems",
  206.     EBADARG, ALL,    "bad arguments to system call",
  207.     EINTRN, ALL,    "internal OS error",
  208.     EPLFMT, E_EXEC,    "bad program load format",
  209.     EGSBF, ALL,    "memory block growth failure",
  210.     EMLINK, ALL,    "too many symbolic links",
  211.     EEXIST, E_CREAT,    "file exists",
  212.     ENAMETOOLONG, ALL, "file name too long",
  213.     ERANGE, ALL,    "math range error",
  214.     EDOM, ALL,    "math domain error"
  215. };
  216.  
  217.  
  218. /*
  219.  * Return a string describing an error.  The returned string may be a
  220.  * pointer to a static buffer that will be overwritten on the next call.
  221.  * Action describes the operation that got the error.
  222.  */
  223.  
  224. char *
  225. errmsg(e, action) {
  226.     struct errname const *ep;
  227.     static char buf[12];
  228.  
  229.     for (ep = errormsg ; ep->errcode ; ep++) {
  230.         if (ep->errcode == e && (ep->action & action) != 0)
  231.             return ep->msg;
  232.     }
  233.     fmtstr(buf, sizeof buf, "error %d", e);
  234.     return buf;
  235. }
  236.